package com.hymjweb.demo.hymj.bill_code_manage.b_native.service;

import com.hymjweb.demo.framework.result.MIniUIGridResultMap;
import com.hymjweb.demo.framework.sys.BaseService;
import com.hymjweb.demo.framework.sys.SysConstant;
import com.hymjweb.demo.framework.util.DataTypeUtil;
import com.hymjweb.demo.framework.util.DateUtil;
import com.hymjweb.demo.hymj.bill_code_manage.b_native.bean.BillNativeCodePojo;
import com.hymjweb.demo.hymj.bill_code_manage.b_native.mapper.BillNativeCodeMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @BelongsProject: demo
 * @BelongsPackage: com.hymjweb.demo.hymj.bill_code_manage.b_native.service
 * @Author: luoge
 * @CreateTime: 2020-10-31 20:29
 * @Description:
 */

@Service
public class BillNativeCodeService extends BaseService {

    /**
     * 生成的单号缓存点
     */
    private static Map<String, Object> billNativeCodeCache = new HashMap<>();

    @Autowired
    private BillNativeCodeMapper billNativeCodeMapper;

    @Value("${nativeBillCode.high.full.zero}")
    private boolean highFullZero;

    @Value("${nativeBillCode.base.length}")
    private int baseLength;

    /**
     * 生成分单号
     *
     * @param map
     * @return
     */
    public boolean generateCode(Map map) throws Exception {

        if (map == null || map.isEmpty()) {
            throwException("分单号生成参数错误!");
        }

        String generateDepartmentId = DataTypeUtil.toNotNullString(map.get("departmentId"));
        String userId = DataTypeUtil.toNotNullString(map.get("userId"));
        String startCode = DataTypeUtil.toNotNullString(map.get("startCode"));
        String endCode = DataTypeUtil.toNotNullString(map.get("endCode"));
        String receiveDate = DataTypeUtil.toNotNullString(map.get("receiveDate"));

        boolean generateStatus = createBillNativeCodeList(startCode, endCode, generateDepartmentId, receiveDate, userId);

        if (generateStatus) {
            return true;
        }

        return false;
    }


    private boolean createBillNativeCodeList(String startCode, String endCode, String generateDepartmentId, String receiveDate, String userId) {

        List<BillNativeCodePojo> billNativeCodePojoList = new ArrayList<>();

        int startBillCode = DataTypeUtil.toInt(startCode);
        int endBillCode = DataTypeUtil.toInt(endCode);

        for (int i = startBillCode; i <= endBillCode; i++) {

            BillNativeCodePojo billNativeCodePojo = new BillNativeCodePojo();
            String billCode = getHighFullZeroCode(i + "");
            billNativeCodePojo.setId(billCode);
            billNativeCodePojo.setUseStatusId(SysConstant.XT_DIC_USE_STATUS.UNUSED.getId());
            billNativeCodePojo.setGenerateDepartmentId(generateDepartmentId);
            billNativeCodePojo.setGenerateDate(DateUtil.strToDate(receiveDate));
            billNativeCodePojo.setGenerateUserId(userId);

            billNativeCodePojoList.add(billNativeCodePojo);
        }

        billNativeCodeCache.put(userId, billNativeCodePojoList);

        return true;
    }

    /**
     * 原始单号高位补0操作
     *
     * @param billCode
     * @return
     */
    private String getHighFullZeroCode(String billCode) {
        StringBuffer fullZeroBillCode = new StringBuffer(billCode);
        if (highFullZero) {
            int fullZeroBillCodeLength = fullZeroBillCode.length();
            if (fullZeroBillCodeLength < baseLength) {
                for (int j = 0; j < baseLength - fullZeroBillCodeLength; j++) {
                    fullZeroBillCode.insert(0, "0");
                }
            }
        }
        return fullZeroBillCode.toString();
    }


    public Object showCode(String userId) {

        if (billNativeCodeCache.containsKey(userId)) {
            List<Object> billNativeCodePojos = (List<Object>) billNativeCodeCache.get(userId);
            MIniUIGridResultMap mIniUIGridResultMap = new MIniUIGridResultMap();
            mIniUIGridResultMap.setData(billNativeCodePojos);
            mIniUIGridResultMap.setTotal(billNativeCodePojos.size());

            billNativeCodeCache.remove(userId);
            return mIniUIGridResultMap;

        }

        return null;
    }

    /**
     * 保存单号
     *
     * @param billNativeCodePojoList
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public boolean saveCode(List<BillNativeCodePojo> billNativeCodePojoList) throws Exception {

        if (billNativeCodePojoList == null || billNativeCodePojoList.isEmpty()) {
            throwException("待保存分单号列为空!");
        }

        // 获取库中现有的所有单号
        List<BillNativeCodePojo> list = findAll(null);

        // 转为map,方便判断
        Map<String, BillNativeCodePojo> maps = convertToMap(list);

        // 将所有要入库的单号加入待入库的List
        List<BillNativeCodePojo> canSaveList = checkCanSaveBillNativeCode(billNativeCodePojoList, maps);

        if(canSaveList == null || canSaveList.isEmpty()){
            throwException("无待入库的分单号!");
        }

        int affectRows = billNativeCodeMapper.batchInsert(canSaveList);

        if (affectRows <= SysConstant.INT_ZERO) {
            return false;
        }
        return true;

    }

    /**
     * 检测可以保存的单号
     *
     * @param rows
     * @param maps
     * @return
     */
    private List<BillNativeCodePojo> checkCanSaveBillNativeCode(List<BillNativeCodePojo> rows, Map<String, BillNativeCodePojo> maps) {
        List<BillNativeCodePojo> canSaveList = new ArrayList<>();
        for (BillNativeCodePojo pojo : rows) {
            if (!maps.containsKey(pojo)) {
                canSaveList.add(pojo);
            }
        }
        return canSaveList;
    }

    /**
     * 查询到的所有单号转为map
     *
     * @param list
     * @return
     */
    private Map<String, BillNativeCodePojo> convertToMap(List<BillNativeCodePojo> list) {
        Map<String, BillNativeCodePojo> map = new HashMap<>();
        for (BillNativeCodePojo pojo : list) {
            map.put(pojo.getId(), pojo);
        }
        return map;
    }


    /**
     * 查询所有存在的单号,无分页功能
     *
     * @param map
     * @return
     */
    public List<BillNativeCodePojo> findAll(Map map) {
        List<BillNativeCodePojo> billNativeCodePojoList = billNativeCodeMapper.findAll(map);
        return billNativeCodePojoList;
    }


    /**
     * 根据条件查询单号，具有分页功能
     *
     * @param map
     * @return
     */
    public Object queryBillNativeCodeList(Map<String, Object> map) {
        this.pageListInit(map);
        List list = findAll(map);
        MIniUIGridResultMap resultMap = this.pageToGrid(list);
        return resultMap;
    }

    /**
     * 根据分单号id检测该分单号是否可用
     *
     * @param billCodeId
     * @return
     */
    public boolean checkBillCodeId(String billCodeId) throws Exception {
        if (DataTypeUtil.isEmptyStr(billCodeId)) {
            throwException("待检测分单号为空!");
        }
        /**
         * select t.* from b_native_bill_code t
         * where 1=1
         *       -- and t.id=''
         *       -- and t.use_status_id=241
         *       -- and t.generate_department_id = ''
         *       and t.use_department_id is null
         *       and t.use_user_id is null
         */
        Long useStatusId = SysConstant.XT_DIC_USE_STATUS.UNUSED.getId();
        String generateDepartmentId = getSystemUserDepartment().getId();

        BillNativeCodePojo pojo = billNativeCodeMapper.checkBillCodeIdUseStatus(billCodeId, useStatusId, generateDepartmentId);
        if (pojo != null) {
            return true;
        }
        return false;
    }

    /**
     * 标识分单号已经被使用
     *
     * @param id
     * @return
     */
    @Transactional(rollbackFor = {Exception.class})
    public int updateBillCodeStatus(String id, Long useStatusId, String userDepartmentId, String useUserId) {

        BillNativeCodePojo billNativeCodePojo = billNativeCodeMapper.getBillNativeCodePojoById(id);
        // 设置使用状态
        billNativeCodePojo.setUseStatusId(useStatusId);
        billNativeCodePojo.setUseDepartmentId(userDepartmentId);
        billNativeCodePojo.setUseUserId(useUserId);

        return billNativeCodeMapper.update(billNativeCodePojo);
    }


    @Transactional(rollbackFor = {Exception.class})
    public int deleteNativeBillCode(Map param) throws Exception {

        if (param == null || param.isEmpty()) {
            throwException("分单号删除参数错误!");
        }
        // {deleteNativeBillCodes:canDeleteCodes}
        String deleteNativeBillCodes = DataTypeUtil.toStringObject(param.get("deleteNativeBillCodes"));
        if (DataTypeUtil.isEmptyStr(deleteNativeBillCodes)) {
            throwException("分单号删除参数错误!");
        }

        String[] deleteNativeBillCodeArray = deleteNativeBillCodes.split(",");
        if (deleteNativeBillCodeArray == null || deleteNativeBillCodeArray.length == 0) {
            throwException("分单号删除待删除分单号不存在!");
        }

        int affectRows = SysConstant.INT_ZERO;
        for (String billCode : deleteNativeBillCodeArray) {
            affectRows += this.delete(billCode);
        }


        return affectRows;
    }

    @Transactional(rollbackFor = {Exception.class})
    public int delete(String billCode) throws Exception {
        if (DataTypeUtil.isEmptyStr(billCode)) {
            throwException("分单号删除待删除分单号不存在!");
        }
        return billNativeCodeMapper.delete(billCode);
    }
}
